package br.com.beans;

import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import br.com.dao.EspecialidadeDAO;
import br.com.dao.MedicoDAO;
import br.com.dao.UsuarioDAO;

/** Classe que representa um medico */
@Entity
@Table(name="tb_medico")
public class Medico {
	
	/** Usuario do sistema associado ao medico */
	@Id
	private MedicoPK medicoPK = new MedicoPK();

	/** Especialidade do medico */
	@ManyToOne
    @JoinColumn(name="codigoEspecialidade",nullable=false)
	private Especialidade especialidade = new Especialidade();
		
	/** Construtor padrao */
	public Medico() {
		getUsuario().setNivel(Usuario.Nivel.MEDICO);
	}

	/** Construtor de copia */
	public Medico(Medico medico) {
		copiar(medico);
	}

	/** Limpa todos atributos. */
	public void limpar() {
		setUsuario(new Usuario());
		setEspecialidade(new Especialidade());
	}

	/** Copia atributos de outro objeto.
	 *  @param obj Objeto a ser copiado */
	public void copiar(Medico obj) {
		if (obj != null) {
			setEspecialidade(new Especialidade(obj.getEspecialidade()));
			setUsuario(new Usuario(obj.getUsuario()));
		} else {
			limpar();
		}
	}
	
	/** Cadastra um medico. */
	public void cadastrar() {
		MedicoDAO        medicoDAO        = new MedicoDAO();
		EspecialidadeDAO especialidadeDAO = new EspecialidadeDAO();
		UsuarioDAO       usuarioDAO       = new UsuarioDAO();
		FacesMessage facesMessage = null;

		getUsuario().setNivel(Usuario.Nivel.MEDICO);
		getUsuario().setSenha(getUsuario().getUserName());

		Especialidade especialidadeObj = especialidadeDAO.localizar(getEspecialidade().getDescricao());
		if (especialidadeObj != null) setEspecialidade(especialidadeObj);

		
		if (!usuarioDAO.inserir(getUsuario())) {
			facesMessage = new FacesMessage("Erro ao adicionar medico.",null);  
			FacesContext.getCurrentInstance().addMessage(null,facesMessage);
			return;
		}
		
		Usuario usuarioObj = usuarioDAO.localizar(getUsuario().getUserName());
		if (usuarioObj != null) setUsuario(usuarioObj);
		
		if (medicoDAO.inserir(this)) {
			facesMessage = new FacesMessage("Medico adicionado com sucesso.",null);  
			limpar();
		} else {
			facesMessage = new FacesMessage("Erro ao adicionar medico.",null);  
		}
		FacesContext.getCurrentInstance().addMessage(null,facesMessage);  
	}

	/** Remove um medico. */
	public void remover() {
		MedicoDAO  medicoDAO  = new MedicoDAO();
		UsuarioDAO usuarioDAO = new UsuarioDAO();
		FacesMessage facesMessage = null;
		if (medicoDAO.excluir(getUsuario().getUserName()) &&
				usuarioDAO.excluir(getUsuario().getUserName())) {
			facesMessage = new FacesMessage("Medico removido com sucesso.",null);  
		} else {
			facesMessage = new FacesMessage("Erro ao remover medico.",null);  
		}
		limpar();
		FacesContext.getCurrentInstance().addMessage(null,facesMessage);  
	}
	
	/** Retorna uma lista de medicos.
	 * @return Lista de medicos. */
	public List<Medico> getLista() {
		MedicoDAO medicoDAO = new MedicoDAO();
		return medicoDAO.listar();
	}

	/** Retorna uma lista de nomes de medicos.
	 * @return Lista de nomes de medicos. */
	public Set<String> getListaNome() {
		MedicoDAO medicoDAO = new MedicoDAO();
		Set<String> resultado = new TreeSet<String>();

		List<Medico> listaMedicos = medicoDAO.listar();
		if (listaMedicos != null) {
			for (Medico medicoObj : listaMedicos) {
				resultado.add(medicoObj.getUsuario().getNome());
			}
		}
		return resultado;
	}
	
	public Especialidade getEspecialidade() {
		return especialidade;
	}

	public void setEspecialidade(Especialidade especialidade) {
		this.especialidade = especialidade;
	}

	public void setUsuario(Usuario usuario) {
		medicoPK.setUsuario(usuario);
	}

	public Usuario getUsuario() {
		return medicoPK.getUsuario();
	}

	public MedicoPK getMedicoPK() {
		return medicoPK;
	}

	public void setMedicoPK(MedicoPK medicoPK) {
		this.medicoPK = medicoPK;
	}
}
